﻿
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MetroNextTools.NBase
{
    /// <summary>
    /// 拥有模版属性的对象需要继承这个类
    /// </summary>
    public abstract class NTemplateControl : NControl
    {
        #region Fields
        internal DataTemplate _itemTemplateCache;
        internal DataTemplateSelector _itemTemplateSelectorCache;
        internal Style _itemContainerStyleCache;
        internal StyleSelector _itemContainerStyleSelectorCache;
        internal string _displayMemberPathCache = null;
        #endregion

        #region ItemTemplate Property

        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }

        public static readonly DependencyProperty ItemTemplateProperty =
            DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(NTemplateControl), new PropertyMetadata(null,new PropertyChangedCallback(OnItemTemplateChanged)));

        private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NTemplateControl ctrl = (NTemplateControl)d;
            ctrl._itemTemplateCache = (DataTemplate)e.NewValue;
            ctrl.OnItemTemplateChanged((DataTemplate)e.OldValue);
            ctrl.InvalidateUI();
        }

        #endregion

        #region ItemTemplateSelector Property

        public DataTemplateSelector ItemTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }

        public static readonly DependencyProperty ItemTemplateSelectorProperty =
            DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(NTemplateControl), new PropertyMetadata(new PropertyChangedCallback(OnItemTemplateSelectorChanged)));

        private static void OnItemTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NTemplateControl ctrl = (NTemplateControl)d;
            ctrl._itemTemplateSelectorCache = (DataTemplateSelector)e.NewValue;
            ctrl.OnItemTemplateSelectorChanged((DataTemplateSelector)e.OldValue);
            ctrl.InvalidateUI();
        }

        #endregion

        #region ItemContainerStyle Property

        public Style ItemContainerStyle
        {
            get { return (Style)GetValue(ItemContainerStyleProperty); }
            set { SetValue(ItemContainerStyleProperty, value); }
        }

        public static readonly DependencyProperty ItemContainerStyleProperty =
            DependencyProperty.Register("ItemContainerStyle", typeof(Style), typeof(NTemplateControl), new PropertyMetadata(new PropertyChangedCallback(OnItemContainerStyleChanged)));

        private static void OnItemContainerStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NTemplateControl ctrl = (NTemplateControl)d;
            ctrl._itemContainerStyleCache = (Style)e.NewValue;
            ctrl.OnItemContainerStyleChanged((Style)e.OldValue);
            ctrl.InvalidateUI();
        }

        #endregion

        #region ItemContainerStyleSelector Property

        public StyleSelector ItemContainerStyleSelector
        {
            get { return (StyleSelector)GetValue(ItemContainerStyleSelectorProperty); }
            set { SetValue(ItemContainerStyleSelectorProperty, value); }
        }

        public static readonly DependencyProperty ItemContainerStyleSelectorProperty =
            DependencyProperty.Register("ItemContainerStyleSelector", typeof(StyleSelector), typeof(NTemplateControl), new PropertyMetadata(new PropertyChangedCallback(OnItemContainerStyleSelectorChanged)));

        private static void OnItemContainerStyleSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NTemplateControl ctrl = (NTemplateControl)d;
            ctrl._itemContainerStyleSelectorCache = (StyleSelector)e.NewValue;
            ctrl.OnItemContainerStyleSelectorChanged((StyleSelector)e.OldValue);
            ctrl.InvalidateUI();
        }

        #endregion

        #region DisplayMemberPath Property

        public string DisplayMemberPath
        {
            get { return (string)GetValue(DisplayMemberPathProperty); }
            set { SetValue(DisplayMemberPathProperty, value); }
        }

        public static readonly DependencyProperty DisplayMemberPathProperty =
            DependencyProperty.Register("DisplayMemberPath", typeof(string), typeof(NTemplateControl), new PropertyMetadata(string.Empty,new PropertyChangedCallback(OnDisplayMemberPathChanged)));

        private static void OnDisplayMemberPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NTemplateControl ctrl = (NTemplateControl)d;
            ctrl._displayMemberPathCache = (string)e.NewValue;
            ctrl.OnDisplayMemberPathChanged((string)e.OldValue);
        }

        #endregion

        #region Method

        protected virtual void OnItemTemplateChanged(DataTemplate oldDataTemplate)
        {
            
        }

        protected virtual void OnItemTemplateSelectorChanged(DataTemplateSelector oldDataTemplateSelector)
        {
            
        }

        protected virtual void OnItemContainerStyleChanged(Style oldStyle)
        {
            
        }

        private void OnItemContainerStyleSelectorChanged(StyleSelector oldStyleSelector)
        {
            
        }

        private void OnDisplayMemberPathChanged(string oldDisplayMemberPath)
        {
            
        }

        protected virtual void InvalidateUI()
        {

        }

        internal virtual DataTemplate GetItemTemplate(object dataItem, DependencyObject container)
        {
            if (this._itemTemplateSelectorCache != null)
            {
                return this._itemTemplateSelectorCache.SelectTemplate(dataItem, container);
            }
            return this._itemTemplateCache;
        }

        internal virtual Style GetItemContainerStyle(object dataItem, DependencyObject container)
        {
            if (this._itemContainerStyleSelectorCache != null)
            {
                return this._itemContainerStyleSelectorCache.SelectStyle(dataItem, container);
            }
            return _itemContainerStyleCache;
        }
        #endregion
        
    }
}
